/**
 * @file app_flash_config.h
 * @brief 应用层Flash配置参数管理头文件
 * @author Claude Code
 * @date 2025-08-09
 * @note 基于drv_flash驱动层，提供业务相关的参数管理功能
 */

#ifndef APP_FLASH_CONFIG_H
#define APP_FLASH_CONFIG_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <stdbool.h>
#include "drv_flash.h"
#include "user_config.h"

/* ================= 应用配置 ================= */

/** @brief 用户数据存储页地址 - 使用最后一页避免覆盖程序 */
#ifndef APP_FLASH_SIZE_KB
#define APP_FLASH_SIZE_KB 64 // 默认Flash大小为64KB
#endif
#define APP_FLASH_USER_PAGE_ADDR    (0x08000000 + (APP_FLASH_SIZE_KB - 1) * 1024)

/** @brief 数据结构版本号 - 升级时可检测数据兼容性 */
#define APP_FLASH_DATA_VERSION      0x01

/** @brief 数据有效性标志 */
#define APP_FLASH_VALID_FLAG        0xAA55

/* ================= 数据结构定义 ================= */

/**
 * @brief 用户参数结构体
 * @note 添加新参数时，需更新版本号和CRC计算
 */
typedef struct {
    uint16_t valid_flag;        ///< 数据有效性标志
    uint16_t version;           ///< 数据结构版本
    
    // 电磁铁参数
    uint8_t solenoid_hit_duration_yany;  ///< 延音踏板打击时间(ms) 0-127
    uint8_t solenoid_hit_duration_ruoy;  ///< 弱音踏板打击时间(ms) 0-127
    
    // 预留参数空间
    uint8_t reserved[10];       ///< 预留字段，便于后续扩展
    
    uint16_t crc16;             ///< CRC16校验值
} app_flash_user_params_t;

/**
 * @brief Flash配置操作状态枚举
 */
typedef enum {
    APP_FLASH_OK = 0,           ///< 操作成功
    APP_FLASH_ERROR,            ///< 通用错误
    APP_FLASH_ERROR_CRC,        ///< CRC校验错误
    APP_FLASH_ERROR_INVALID,    ///< 数据无效
    APP_FLASH_ERROR_PARAM       ///< 参数错误
} app_flash_status_t;

/* ================= 默认参数定义 ================= */

/** @brief 默认延音踏板打击时间(ms) */
#define APP_FLASH_DEFAULT_YANY_HIT_DURATION     APP_PEDAL_HIT_DURATION_INIT

/** @brief 默认弱音踏板打击时间(ms) */
#define APP_FLASH_DEFAULT_RUOY_HIT_DURATION     APP_PEDAL_HIT_DURATION_INIT

/* ================= 函数声明 ================= */

/**
 * @brief 初始化Flash配置模块
 * @note 建议在系统初始化时调用
 * @retval APP_FLASH_OK 初始化成功
 * @retval 其他值 初始化失败
 */
app_flash_status_t app_flash_config_init(void);

/**
 * @brief 读取用户参数
 * @param params 参数结构体指针
 * @retval APP_FLASH_OK 读取成功
 * @retval APP_FLASH_ERROR_INVALID 数据无效，已加载默认值
 * @retval APP_FLASH_ERROR_CRC CRC校验失败
 */
app_flash_status_t app_flash_read_user_params(app_flash_user_params_t* params);

/**
 * @brief 写入用户参数
 * @param params 参数结构体指针
 * @retval APP_FLASH_OK 写入成功
 * @retval 其他值 写入失败
 */
app_flash_status_t app_flash_write_user_params(const app_flash_user_params_t* params);

/**
 * @brief 恢复默认参数并写入Flash
 * @retval APP_FLASH_OK 恢复成功
 * @retval 其他值 恢复失败
 */
app_flash_status_t app_flash_restore_defaults(void);

/**
 * @brief 获取默认参数
 * @param params 参数结构体指针
 * @note 填充默认值，不进行Flash操作
 */
void app_flash_get_default_params(app_flash_user_params_t* params);

/**
 * @brief 检查参数有效性
 * @param params 参数结构体指针
 * @retval true 参数有效
 * @retval false 参数无效
 */
bool app_flash_is_params_valid(const app_flash_user_params_t* params);

/**
 * @brief 计算参数CRC16
 * @param params 参数结构体指针
 * @retval CRC16校验值
 */
uint16_t app_flash_calc_params_crc(const app_flash_user_params_t* params);

/* ================= 便利函数 ================= */

/**
 * @brief 快速设置电磁铁打击时间
 * @param yany_duration 延音踏板打击时间(ms) 0-127
 * @param ruoy_duration 弱音踏板打击时间(ms) 0-127
 * @retval APP_FLASH_OK 设置成功
 * @retval 其他值 设置失败
 */
app_flash_status_t app_flash_set_solenoid_durations(uint8_t yany_duration, uint8_t ruoy_duration);

/**
 * @brief 快速获取电磁铁打击时间
 * @param yany_duration 延音踏板打击时间输出指针
 * @param ruoy_duration 弱音踏板打击时间输出指针
 * @retval APP_FLASH_OK 获取成功
 * @retval 其他值 获取失败，已返回默认值
 */
app_flash_status_t app_flash_get_solenoid_durations(uint8_t* yany_duration, uint8_t* ruoy_duration);

#ifdef __cplusplus
}
#endif

#endif /* APP_FLASH_CONFIG_H */
